Zjisteni lokalni IP

Otázka od: Jakub Cermak

14. 11. 2004 15:03

Vim, ze je to zacatecnicky dotaz, ale nejak na to nemuzu prijit. Mam
otevreny a funkcni serverovy UDP socket (nemyslim listening) a potrebuju
nejak zjistit lokalni IP adresu rozhrani, pres kterou pozadavek prisel.
Trochu sem hledal a nasel clanek
"Getsockname() Returns IP Address 0.0.0.0
for UDP"
http://support.microsoft.com/default.aspx?scid=kb;en-us;129065 na
MSDN, kde je napsany ze to nejde, coz se mi nezda, protoze jak se rika
vsechno jde kdyz se chce. Nevite nekdo jak na to??

Jakub Cermak
ja.cermi@centrum.cz


Odpovedá: l. vlcek

15. 11. 2004 10:11

Jakub Cermak napsal(a):
> Vim, ze je to zacatecnicky dotaz, ale nejak na to nemuzu prijit. Mam
> otevreny a funkcni serverovy UDP socket (nemyslim listening) a potrebuju
> nejak zjistit lokalni IP adresu rozhrani, pres kterou pozadavek prisel.
???
lokalni adresa je typicky: 127.0.0.1, zvany loopback....

Jestli mas na mysli adresu spojeni, ktere jsi otevrel proti jinemu
stroji, tak to "obvykle" byva adresa sitovky (pokud jich nemas vic).
 

--
L.V.
jezevec


Odpovedá: Jakub Cermak

15. 11. 2004 19:32

No prave ze tech sitovek je vic. To ze loopback je 127.0.0.1 vim  .

Jakub Cermak
ja.cermi@centrum.cz

----- Original Message -----
From: "l. vlcek" <l.vlcek@noel-plus.cz>
To: <delphi-l@clexpert.cz>
Sent: Monday, November 15, 2004 10:10 AM
Subject: Re: Zjisteni lokalni IP


> Jakub Cermak napsal(a):
>> Vim, ze je to zacatecnicky dotaz, ale nejak na to nemuzu prijit. Mam
>> otevreny a funkcni serverovy UDP socket (nemyslim listening) a potrebuju
>> nejak zjistit lokalni IP adresu rozhrani, pres kterou pozadavek prisel.
> ???
> lokalni adresa je typicky: 127.0.0.1, zvany loopback....
>
> Jestli mas na mysli adresu spojeni, ktere jsi otevrel proti jinemu
> stroji, tak to "obvykle" byva adresa sitovky (pokud jich nemas vic).
>  
>
> --
> L.V.
> jezevec
>
>
>


Odpovedá: l. vlcek

16. 11. 2004 7:51

Jakub Cermak napsal(a):
> No prave ze tech sitovek je vic. To ze loopback je 127.0.0.1 vim  .
>
jo,
tyhle informace si drzi datova struktura vazana k socketu. Pristup k nim
se muze lisit v "urovni konfortu", nebo jak bych to rekl.
Kazda socketova knihovna obvykle tyto data kopiruje ve svych vlastnich
strukturach (indy (tusim) v objektech bind nebo neco podobneho...). Lze
to najit v dokumentaci prislusne knihovny. Dobre byva podivat se i na
doprovodne priklady. U indy i (treba) u synapse od L.Gebauera jsou
pomerne primocare....

Jako (obvykle) "posledni pomoc" lze pouzit:
http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/winsock/winsock/sockaddr_storage_2.asp

>>--
>>L.V.
>>jezevec
>>
>>
>>
>
>
>
>


Odpovedá: Jakub Cermak

16. 11. 2004 20:06

No a prave v tom je ten problem. IP adresa (konkretne vlastnost IP) ziskana
pres Indy je 0.0.0.0, pres objekt ABinding: TIdSocketHandle v udalosti
OnUDPRead. Jinak je mi celkem jedno, jakou knihovnu pouziju, ani API mi neni
cizi. Ale "znervoznuje" me to ze na MSDN pisou ze pro udp to nejde, coz me
prijde prinejmensim podivne.

Jakub Cermak
ja.cermi@centrum.cz
ICQ 159971304
http://cermi.wz.cz
PGP key: http://cermi.wz.cz/disk/pub_key.asc
----- Original Message -----
From: "l. vlcek" <l.vlcek@noel-plus.cz>
To: <delphi-l@clexpert.cz>
Sent: Tuesday, November 16, 2004 7:24 AM
Subject: Re: Zjisteni lokalni IP


> Jakub Cermak napsal(a):
>> No prave ze tech sitovek je vic. To ze loopback je 127.0.0.1 vim  .
>>
> jo,
> tyhle informace si drzi datova struktura vazana k socketu. Pristup k nim
> se muze lisit v "urovni konfortu", nebo jak bych to rekl.
> Kazda socketova knihovna obvykle tyto data kopiruje ve svych vlastnich
> strukturach (indy (tusim) v objektech bind nebo neco podobneho...). Lze
> to najit v dokumentaci prislusne knihovny. Dobre byva podivat se i na
> doprovodne priklady. U indy i (treba) u synapse od L.Gebauera jsou
> pomerne primocare....
>
> Jako (obvykle) "posledni pomoc" lze pouzit:
> http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/winsock/winsock/sockaddr_storage_2.asp
>
>>>--
>>>L.V.
>>>jezevec
>>>
>>>
>>>
>>
>>
>>
>>
>
>
>
>


Odpovedá: Dalibor Toman

18. 11. 2004 9:56

DD,

On Tuesday, November 16, 2004 8:05 PM [CET], Jakub Cermak
<cermiforum@centrum.cz> wrote:

> No a prave v tom je ten problem. IP adresa (konkretne vlastnost IP)
> ziskana pres Indy je 0.0.0.0, pres objekt ABinding: TIdSocketHandle
v
> udalosti OnUDPRead. Jinak je mi celkem jedno, jakou knihovnu
pouziju,
> ani API mi neni cizi. Ale "znervoznuje" me to ze na MSDN pisou ze
pro
> udp to nejde, coz me prijde prinejmensim podivne.

podivne to neni:

1) pokud chces zjistit z jake IP adresy prisel UDP packet, _musis_
pouzit pro precteni packetu funkci recvfrom() - ta vraci krome packetu
i adresu odesilatele.

2) UDP se od TCP lisi tim, ze je bezspojove (connectionless) - UDP
socket neni pevne spojen s zadnou konkretni vzdalenou IP adresou.
Teoreticky je sice mozne pomoci connect() "namirit" UDP socket na
konkretni vzdalenou IP adresu ale to se uplatni pouze pri odesilani
packetu (neni treba volat sendto() ale jen send()). Prakticky vyznam
connect() je ale u UDP podle mne nulovy. Na UDP socket po pouziti
connect() stejne muze prijit UDP packet z libovolne adresy.
Protoze UDP neni spojeno se vzdalenou adresou, nemuze Ti system
jednoznacne rict jaka je lokalni adresa (adresa interface), kterym na
nej prisel packet (je to informace vazana na packet ne na socket -
proto ten recvfrom() ). Protoze packet muze prijit libovolnym
rozhranim (ruzne sitovky, localhost atd). Jedine snad na socketu,
ktery byl bind() prilepen k nejakemu konkretnimu rozhrani by Ti mohl
vratit neco smysluplneho (ale byla by to hodnota, kterou jiz znas).

U TCP socketu je po connect() vsechno dane - pomoci routovaci tabulky
je vybrana lokalni IP adresa interface, kterym budou packety prochazet
(pouzije se jako IP adresa odesilatele z tohoto stroje) a ta je
vracena pomoci API funkci jako lokalni IP pro dane TCP spojeni.

Zdravi
Dalibor Toman



Odpovedá: Lukas Gebauer

18. 11. 2004 11:15

> 2) UDP se od TCP lisi tim, ze je bezspojove (connectionless) - UDP
> socket neni pevne spojen s zadnou konkretni vzdalenou IP adresou.
> Teoreticky je sice mozne pomoci connect() "namirit" UDP socket na
> konkretni vzdalenou IP adresu ale to se uplatni pouze pri odesilani
> packetu (neni treba volat sendto() ale jen send()). Prakticky vyznam
> connect() je ale u UDP podle mne nulovy. Na UDP socket po pouziti
> connect() stejne muze prijit UDP packet z libovolne adresy. Protoze

Tohle jsem si kdysi myslel taky, dokud jsem praktickymi testy
neprisel na to, ze se to minimalne na Windows chova jinak!

Zjistil jsem ze kdyz na Windows pouziju pro UDP Connect funkci, pak
pres Recv (ale i pres Recvfrom!) prectu jen ty UDP packety, ktere
prichazi prave z adresy a portu udanem ve volani Connect. Tedy ze
ostatni UDP packety z ostatnich adres jsou tise ignorovany!

Tedy volani Connect pro UDP svuj smysl ma, chova se to pak skutecne
jinak. Ostatne i MSDN o tomto mluvi:

"For a connectionless socket (for example, type SOCK_DGRAM), the
operation performed by connect is merely to establish a default
destination address that can be used on subsequent send/ WSASend and
recv/ WSARecv calls. Any datagrams received from an address other
than the destination address specified will be discarded."


--
Lukas Gebauer.

E-mail: gebauerl@mlp.cz
http://www.ararat.cz/synapse/ - Ararat Synapse - TCP/IP Lib.


Odpovedá: Andreas Bednarek

18. 11. 2004 22:27

Ahoj, cely thread jsem necetl, ale zjistuji IPcka lokalnich sitovek takto
(nekde jsem to kdysi cajznul nebo tak, ale funguje  


procedure LoadIPAddressesToTStrings(aitems : TStrings);
type
 TaPInAddr = array[0..10] of PInAddr;
 PaPInAddr = ^TaPInAddr;
var
 phe : PHostEnt;
 pptr : PaPInAddr;
 Buffer : array [0..255] of Char;
 i : Integer;
 GInitData : TWSADATA;
    err : Integer;

begin

 aitems.Clear;
 err := WSAStartUp($101, GInitData);
    if err = 0 then begin
  i := 0;
  GetHostName(Buffer, SizeOf(Buffer));
  phe := GetHostByName(Buffer);
  if phe = nil then Exit;
     pptr := PaPInAddr(Phe^.h_addr_list);
  while pptr^[i] <> nil do begin
   aitems.Add(StrPas(inet_ntoa(pptr^[i]^)));
   inc(i);
  end;
  WSACleanUp;
    end;

end;

----- Original Message -----
From: "Jakub Cermak" <cermiforum@centrum.cz>
To: <delphi-l@clexpert.cz>
Sent: Monday, November 15, 2004 7:31 PM
Subject: Re: Zjisteni lokalni IP


> No prave ze tech sitovek je vic. To ze loopback je 127.0.0.1 vim  .
>
> Jakub Cermak
> ja.cermi@centrum.cz
>
> ----- Original Message -----
> From: "l. vlcek" <l.vlcek@noel-plus.cz>
> To: <delphi-l@clexpert.cz>
> Sent: Monday, November 15, 2004 10:10 AM
> Subject: Re: Zjisteni lokalni IP
>
>
>> Jakub Cermak napsal(a):
>>> Vim, ze je to zacatecnicky dotaz, ale nejak na to nemuzu prijit. Mam
>>> otevreny a funkcni serverovy UDP socket (nemyslim listening) a potrebuju
>>> nejak zjistit lokalni IP adresu rozhrani, pres kterou pozadavek prisel.
>> ???
>> lokalni adresa je typicky: 127.0.0.1, zvany loopback....
>>
>> Jestli mas na mysli adresu spojeni, ktere jsi otevrel proti jinemu
>> stroji, tak to "obvykle" byva adresa sitovky (pokud jich nemas vic).
>>  
>>
>> --
>> L.V.
>> jezevec
>>
>>
>>
>
>
>


Odpovedá: Jan Novak

20. 11. 2004 12:50

> potrebuju nejak zjistit lokalni IP adresu rozhrani,
> pres kterou UDP pozadavek prisel.

To jsem nenasel nikde, ale dalo by se to udelat tak, ze naslouchas na
kazdem interface socketem pojmenovanym podle site, do ktere je ten
interface pripojen. A podle socketu, ze ktereho to prislo, urcis
interface.

Ve Windows dostanes seznam interfejsu volanim WSAIoctl s funkci
SIO_ADDRESS_LIST_QUERY a v linuxu je to getifaddrs. Z nabizeneho
seznamu vybirej jen IPv4 (sin_family = AF_INET) polozky.